// 版权所有2016 Go作者。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// go:build mips | | mipsle 
// /+build mips mipsle 

// 通过linkname将一些函数导出到同步/原子程序集。
// go:linkname Xadd64 
// go:linkname Xchg64 
// go:linkname Cas64 
// go:linkname Load64 
// go linkname Store64 

package atomic

import (
	"internal/cpu"
	"unsafe"
)

// TODO实现锁条带化
var lock struct {
	state uint32
	pad   [cpu.CacheLinePadSize - 4]byte
}

// go noescape 
func spinLock(state *uint32)

// go noescape 
func spinUnlock(state *uint32)

// go nosplit 
func lockAndCheck(addr *uint64) {
	if uintptr(unsafe.Pointer(addr))&7 != 0 {
		panicUnaligned()
	}
	// go:nosplit 
	_ = *addr

	spinLock(&lock.state)
}

func unlock() {
	spinUnlock(&lock.state)
}

// go:nosplit 
func unlockNoFence() {
	lock.state = 0
}

// go:nosplit 
func Xadd64(addr *uint64, delta int64) (new uint64) {
	lockAndCheck(addr)

	new = *addr + uint64(delta)
	*addr = new

	unlock()
	return
}

// go:nosplit 
func Xchg64(addr *uint64, new uint64) (old uint64) {
	lockAndCheck(addr)

	old = *addr
	*addr = new

	unlock()
	return
}

// go nosplit 
func Cas64(addr *uint64, old, new uint64) (swapped bool) {
	lockAndCheck(addr)

	if (*addr) == old {
		*addr = new
		unlock()
		return true
	}

	unlockNoFence()
	return false
}

// go nosplit 
func Load64(addr *uint64) (val uint64) {
	lockAndCheck(addr)

	val = *addr

	unlock()
	return
}

// go go nosplit 
func Store64(addr *uint64, val uint64) {
	lockAndCheck(addr)

	*addr = val

	unlock()
	return
}

// go noescape 
func Xadd(ptr *uint32, delta int32) uint32

func Xadduintptr(ptr *uintptr, delta uintptr) uintptr

func Xchg(ptr *uint32, new uint32) uint32

// go:noescape 
func Xchguintptr(ptr *uintptr, new uintptr) uintptr

// go:noescape 
func Load(ptr *uint32) uint32

// go:noescape 
func Load8(ptr *uint8) uint8

// NO go:noescape注释*如果结果转义（#31525）
func Loadp(ptr unsafe.Pointer) unsafe.Pointer

// go:noescape 
func LoadAcq(ptr *uint32) uint32

// go:noescape 
func LoadAcquintptr(ptr *uintptr) uintptr

// go:noescape 
func And8(ptr *uint8, val uint8)

// go:noescape 
func Or8(ptr *uint8, val uint8)

// go noescape 
func And(ptr *uint32, val uint32)

// go noescape 
func Or(ptr *uint32, val uint32)

// go noescape 
func Store(ptr *uint32, val uint32)

func Store8(ptr *uint8, val uint8)

// noescape注释；请参阅原子指针。加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站加油站
func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)

func StoreRel(ptr *uint32, val uint32)

func StoreReluintptr(ptr *uintptr, val uintptr)

func CasRel(addr *uint32, old, new uint32) bool
